use cmsis_rtos2_rs::static_mem::MutexValue;
use periph_utils::stm32f1;
use periph_utils::GpioConfig;
use periph_utils::TimPwm2;
use utils::BitCtrl;

#[derive(GpioConfig)]
#[gpio(init = "gpio_init",
    io(name = "heat_steam", io = "PB0", mode = "AF_PP"),  // 0  TIM3_CH3
    io(name = "heat_water", io = "PB9", mode = "AF_PP"), // 1 TIM4_CH4
    io(name = "v3", io = "PB10", mode = "OUT_PP", set, reset), // 2
    io(name = "v4", io = "PB11", mode = "OUT_PP", set, reset), // 3
    io(name = "bucket2_pump", io = "PB12", mode = "OUT_PP", set, reset), // 4
    io(name = "bucket1_pump", io = "PB13", mode = "OUT_PP", set, reset), // 5
    io(name = "v6", io = "PB14", mode = "OUT_PP", set, reset), // 6
    io(name = "v7", io = "PB15", mode = "OUT_PP", set, reset), // 7
    io(name = "v2", io = "PC8", mode = "OUT_PP", set, reset), // 8
    io(name = "v1", io = "PC9", mode = "OUT_PP", set, reset), // 9
    io(name = "clamp_valve", io = "PC10", mode = "OUT_PP", set, reset), // 10
    io(name = "trun_valve", io = "PC11", mode = "OUT_PP", set, reset), // 11
    io(name = "water_pump", io = "PC12", mode = "OUT_PP", set, reset), // 12
    io(name = "steam_pump", io = "PC13", mode = "OUT_PP", set, reset), // 13
    io(name = "v8", io = "PC14", mode = "OUT_PP", set, reset), // 14
    io(name = "air_pump", io = "PC15", mode = "OUT_PP", set, reset), // 15
)]
struct Pin;

const PWM_MAX_VALUE: u16 = 20000;

#[derive(TimPwm2)]
#[pwm(
    init = "pwm_init", 
    tim = "TIM3", 
    psc = 7199, 
    arr = 19999,
    ch(name = "steam", ch = 3, mode = 1)
)]
struct HeatSteam;

#[derive(TimPwm2)]
#[pwm(
    init = "pwm_init", 
    tim = "TIM4", 
    psc = 7199, 
    arr = 19999,
    ch(name = "water", ch = 4, mode = 1)
)]
struct HeatWater;

static FLAG: MutexValue<u16> = MutexValue::uninit(0);

pub unsafe fn init() {
    Pin::gpio_init();
    HeatSteam::pwm_init();
    HeatWater::pwm_init();
    FLAG.init_once("ctrl flag");

    v8_open();
}

pub fn flag_value() -> u16 {
    *FLAG.lock()
}

pub fn heat_steam_open() {
    // let tim3: TIM3 = unsafe { mem::transmute(()) };
    // tim3.ccr3().write(|w| w.ccr().variant(PWM_MAX_VALUE));

   // Pin::heat_steam_set();
    HeatSteam::set_steam_ccr(PWM_MAX_VALUE);
    FLAG.lock().set_bit(0);
}

pub fn heat_steam_close() {
    // let tim3: TIM3 = unsafe { mem::transmute(()) };
    // tim3.ccr3().write(|w| w.ccr().variant(0));
   // Pin::heat_steam_reset();
    HeatSteam::set_steam_ccr(0);
    FLAG.lock().clr_bit(0);
}

pub fn heat_steam_set_value(value: u8) {
    // let tim3: TIM3 = unsafe { mem::transmute(()) };
    // tim3.ccr3().write(|w| w.ccr().variant(value as u16 * 1000));
    HeatSteam::set_steam_ccr(value as u16 * 1000);
    FLAG.lock().set_bit(0);
}

pub fn heat_water_open() {
    // Pin::heat_water_set();
    // let tim4: TIM4 = unsafe { mem::transmute(()) };
    // tim4.ccr4().write(|w| w.ccr().variant(PWM_MAX_VALUE));
    HeatWater::set_water_ccr(PWM_MAX_VALUE);
    FLAG.lock().set_bit(1);
}

pub fn heat_water_close() {
    //  Pin::heat_water_reset();
    // let tim4: TIM4 = unsafe { mem::transmute(()) };
    // tim4.ccr4().write(|w| w.ccr().variant(0));
    HeatWater::set_water_ccr(0);
    FLAG.lock().clr_bit(1);
}

// 1..=15
pub fn heat_water_set_value(value: u8) {
    // let tim4: TIM4 = unsafe { mem::transmute(()) };
    // tim4.ccr4().write(|w| w.ccr().variant(value as u16 * 1333));
    HeatWater::set_water_ccr(value as u16 * 1333);
    FLAG.lock().set_bit(1);
}

pub fn v3_open() {
    Pin::v3_set();
    FLAG.lock().set_bit(2);
}

pub fn v3_close() {
    Pin::v3_reset();
    FLAG.lock().clr_bit(2);
}

pub fn v4_open() {
    Pin::v4_set();
    FLAG.lock().set_bit(3);
}

pub fn v4_close() {
    Pin::v4_reset();
    FLAG.lock().clr_bit(3);
}

pub fn bucket2_pump_open() {
    Pin::bucket2_pump_set();
    FLAG.lock().set_bit(4);
}

pub fn bucket2_pump_close() {
    Pin::bucket2_pump_reset();
    FLAG.lock().clr_bit(4);
}

pub fn bucket1_pump_open() {
    Pin::bucket1_pump_set();
    FLAG.lock().set_bit(5);
}

pub fn bucket1_pump_close() {
    Pin::bucket1_pump_reset();
    FLAG.lock().clr_bit(5);
}

pub fn v6_open() {
    Pin::v6_set();
    FLAG.lock().set_bit(6);
}

pub fn v6_close() {
    Pin::v6_reset();
    FLAG.lock().clr_bit(6);
}

pub fn v7_open() {
    Pin::v7_set();
    FLAG.lock().set_bit(7);
}

pub fn v7_close() {
    Pin::v7_reset();
    FLAG.lock().clr_bit(7);
}

/**
 *  已经取消
 * */
pub fn v2_open() {
    Pin::v2_set();
    FLAG.lock().set_bit(8);
}

/**
 *  已经取消
 * */
pub fn v2_close() {
    Pin::v2_reset();
    FLAG.lock().clr_bit(8);
}

pub fn v1_open() {
    Pin::v1_set();
    FLAG.lock().set_bit(9);
}

pub fn v1_close() {
    Pin::v1_reset();
    FLAG.lock().clr_bit(9);
}

pub fn clamp_valve_open() {
    Pin::clamp_valve_set();
    FLAG.lock().set_bit(10);
}

pub fn clamp_valve_close() {
    Pin::clamp_valve_reset();
    FLAG.lock().clr_bit(10);
}

pub fn trun_valve_open() {
    Pin::trun_valve_set();
    FLAG.lock().set_bit(11);
}

pub fn trun_valve_close() {
    Pin::trun_valve_reset();
    FLAG.lock().clr_bit(11);
}

pub fn water_pump_open() {
    Pin::water_pump_set();
    FLAG.lock().set_bit(12);
}

pub fn water_pump_close() {
    Pin::water_pump_reset();
    FLAG.lock().clr_bit(12);
}

pub fn steam_pump_open() {
    Pin::steam_pump_set();
    FLAG.lock().set_bit(13);
}

pub fn steam_pump_close() {
    Pin::steam_pump_reset();
    FLAG.lock().clr_bit(13);
}

pub fn v8_open() {
    Pin::v8_set();
    FLAG.lock().set_bit(14);
}

pub fn v8_close() {
    Pin::v8_reset();
    FLAG.lock().clr_bit(14);
}

pub fn air_pump_open() {
    Pin::air_pump_set();
    FLAG.lock().set_bit(15);
}

pub fn air_pump_close() {
    Pin::air_pump_reset();
    FLAG.lock().clr_bit(15);
}
